• Home
  • Introduction
  • Data Source
  • Data Visualization
  • Exploratory Data Analysis
  • ARMA/ARIMA/SARIMA Model
  • ARIMAX Model
  • Financial Time Series Model
  • Deep Learning for TS
  • Conclusion

EDA for Industrial Sector Fund

The Industrial Sector Fund (XLI) is an exchange-traded fund that tracks the performance of companies in the industrial sector of the US stock market. This sector includes companies involved in manufacturing, transportation, and construction, among others. XLI provides investors with exposure to this sector and has holdings in companies such as Boeing, Honeywell, and General Electric. The performance of XLI is closely tied to the overall health of the US economy, as the industrial sector is a key driver of economic growth.

Time Series Plot
Code
# get data
options("getSymbols.warning4.0"=FALSE)
options("getSymbols.yahoo.warning"=FALSE)


data = getSymbols("XLI",src='yahoo', from = '2010-01-01',to = "2023-03-01")

df <- data.frame(Date=index(XLI),coredata(XLI))

# create Bollinger Bands
bbands <- BBands(XLI[,c("XLI.High","XLI.Low","XLI.Close")])

# join and subset data
df <- subset(cbind(df, data.frame(bbands[,1:3])), Date >= "2010-01-01")

#export the data 
XLI_data <- df
write.csv(XLI_data, "DATA/CLEANED DATA/XLI_raw_data.csv", row.names=FALSE)

# colors column for increasing and decreasing
for (i in 1:length(df[,1])) {
  if (df$XLI.Close[i] >= df$XLI.Open[i]) {
      df$direction[i] = 'Increasing'
  } else {
      df$direction[i] = 'Decreasing'
  }
}

i <- list(line = list(color = '#00BFFF'))
d <- list(line = list(color = '#7F7F7F'))

# plot candlestick chart

fig <- df %>% plot_ly(x = ~Date, type="candlestick",
          open = ~XLI.Open, close = ~XLI.Close,
          high = ~XLI.High, low = ~XLI.Low, name = "XLI",
          increasing = i, decreasing = d) 
fig <- fig %>% add_lines(x = ~Date, y = ~up , name = "B Bands",
            line = list(color = '#ccc', width = 0.5),
            legendgroup = "Bollinger Bands",
            hoverinfo = "none", inherit = F) 
fig <- fig %>% add_lines(x = ~Date, y = ~dn, name = "B Bands",
            line = list(color = '#ccc', width = 0.5),
            legendgroup = "Bollinger Bands", inherit = F,
            showlegend = FALSE, hoverinfo = "none") 
fig <- fig %>% add_lines(x = ~Date, y = ~mavg, name = "Mv Avg",
            line = list(color = '#E377C2', width = 0.5),
            hoverinfo = "none", inherit = F) 
fig <- fig %>% layout(yaxis = list(title = "Price"))

# plot volume bar chart
fig2 <- df 
fig2 <- fig2 %>% plot_ly(x=~Date, y=~XLI.Volume, type='bar', name = "XLI Volume",
          color = ~direction, colors = c('#00BFFF','#7F7F7F')) 
fig2 <- fig2 %>% layout(yaxis = list(title = "Volume"))

# create rangeselector buttons
rs <- list(visible = TRUE, x = 0.5, y = -0.055,
           xanchor = 'center', yref = 'paper',
           font = list(size = 9),
           buttons = list(
             list(count=1,
                  label='RESET',
                  step='all'),
             list(count=3,
                  label='3 YR',
                  step='year',
                  stepmode='backward'),
             list(count=1,
                  label='1 YR',
                  step='year',
                  stepmode='backward'),
             list(count=1,
                  label='1 MO',
                  step='month',
                  stepmode='backward')
           ))

# subplot with shared x axis
fig <- subplot(fig, fig2, heights = c(0.7,0.2), nrows=2,
             shareX = TRUE, titleY = TRUE)
fig <- fig %>% layout(title = paste("Industrial Sector Fund Stock Price: JAN 2010 - March 2023"),
         xaxis = list(rangeselector = rs),
         legend = list(orientation = 'h', x = 0.5, y = 1,
                       xanchor = 'center', yref = 'paper',
                       font = list(size = 10),
                       bgcolor = 'transparent'))

fig

The Industrial Sector Fund (XLI) has seen several fluctuations in its performance since 2010. The fund saw a dip in its value during the economic recession of 2010, but it recovered and reached new highs by 2011. The fund continued to perform well until 2015 when it experienced a slump due to concerns about global economic growth and the slowdown in China. However, XLI rebounded again in 2016 and continued to perform well until 2018.

In 2018, the fund saw a decline in value due to concerns over trade wars between the US and China, which impacted the industrial sector negatively. Despite this, the fund managed to recover in 2019 and continued to perform well until early 2020. The COVID-19 pandemic led to a sharp drop in the value of XLI in March 2020. However, the fund rebounded quickly and reached new highs by November 2020, mainly due to the rebounding economy and hopes for a COVID-19 vaccine. The fund continued to perform well in early 2021, but a resurgence of COVID-19 cases and concerns over rising inflation caused some volatility in the market, leading to fluctuations in XLI’s value.

For stock prices, a multiplicative decomposition is typically preferred because the percentage changes in stock prices tend to be more important than the absolute changes. Additionally, stock prices tend to exhibit non-constant variance, meaning that the variance of the series changes over time. A multiplicative decomposition can handle this non-constant variance more effectively than an additive decomposition.

Decomposed Time Series

  • Decomposition Plot
  • Adjusted Decomposition Plot
Code
#time series data
myts<-ts(df$XLI.Adjusted,frequency=252,start=c(2010,01,01), end = c(2023,3,1)) 
#original plot for time series data
orginial_plot <- autoplot(myts,xlab ="Year", ylab = "Adjusted Closing Price", main = "Industrial Sector Fund Stock price: JAN 2010 - March 2023")
#decompose the data
decompose = decompose(myts, "multiplicative")
#decomposition plot
autoplot(decompose)

Code
#adjusted plot
trendadj <- myts/decompose$trend
decompose_adjtrend_plot <- autoplot(trendadj,ylab='trend') +ggtitle('Adjusted trend component in the multiplicative time series model')
seasonaladj <- myts/decompose$seasonal
decompose_adjseasonal_plot <- autoplot(seasonaladj,ylab='seasonal') +ggtitle('Adjusted seasonal component in the multiplicative time series model')
grid.arrange(orginial_plot, decompose_adjtrend_plot,decompose_adjseasonal_plot, nrow=3)

The adjusted seasonal component tend to have upward trend till 2019 and drops during the covid period and there is more variability in the model when compared to the original plot where the variation during the years but the adjusted trend then to have more fluctuation showing no trend when compared to the original plot.

Lag Plots

  • Daily Time Lags
  • Monthly Time Lags
Code
#Lag plots 
gglagplot(myts, do.lines=FALSE, lags=1)+xlab("Lag 1")+ylab("Yi")+ggtitle("Lag Plot for Industrial Sector Fund Stock JAN 2010 - March 2023")

Code
#montly data
mean_data <- df %>% 
  mutate(month = month(Date), year = year(Date)) %>% 
  group_by(year, month) %>% 
  summarize(mean_value = mean(XLI.Adjusted))
month<-ts(mean_data$mean_value,start = c(2010, 1),frequency = 12)
#Lag plot
ts_lags(month)

The first lag plot shows the daily time lags of the Industrial Sector Fund stock price from JAN 2010 to March 2023. The plot indicates that there is a strong positive correlation between the current value and the previous day’s value, as seen by the points clustering along the diagonal line. This suggests that the stock price has a positive autocorrelation at a lag of one day.

The second lag plot shows the monthly time lags of the mean value of the Industrial Sector Fund stock price from JAN 2010 to March 2023. The plot indicates that there is a positive correlation between the current value and the value from the previous month. This suggests that the mean value of the stock price has a positive autocorrelation at a lag of one month.

Overall, the lag plots indicate that there is a positive autocorrelation present in the Industrial Sector Fund stock price data, with the strongest correlation observed in the daily time series.

Seasonality

  • Seasonal Heatmap
  • Seasonal Line plot
Code
# Create seasonal plot
ts_heatmap(month,color = "Greys", title = 'Seasonality Heatmap of Industrial Sector Fund Stock Jan 2010 - March 2023')
Code
# Create a line graph for each year with months on the x-axis
ggseasonplot(month, datecol = "date", valuecol = "value")+ggtitle("Seasonal Yearly Plot for Industrial Sector Fund Stock Jan 2010 - March 2023")

The Seasonality Heatmap for the Industrial Sector Fund Stock JAN 2010 - March 2023 does not reveal any clear seasonality in the data. The heatmap shows the mean value of the time series for each month and year combination, with the darker colors indicating higher values. The lack of clear patterns or darker colors in specific months or years suggests that there is no consistent seasonal pattern in the data. However, the yearly line graph shows a slight upward trend in the stock price from 2010 to 2023, but does not show any clear seasonality. Each year’s data is represented by a line, and the months are plotted on the x-axis. Overall, the lack of clear seasonality in both the heatmap and yearly line graph suggests that other factors beyond seasonality are driving the stock price fluctuations.

Moving Average

  • 4 Month MA
  • 1 Year MA
  • 3 Year MA
  • 5 Year MA
Code
#SMA Smoothing 
ma <- autoplot(month, series="Data") +
  autolayer(ma(month,5), series="4 Month MA") +
  xlab("Year") + ylab("GWh") +
  ggtitle("Industrial Sector Fund Stock JAN 2010 - March 2023(4 Month Moving Average)") +
  scale_colour_manual(values=c("Data"="grey50","4 Month MA"="red"),
                      breaks=c("Data","4 Month MA"))
ma

Code
#SMA Smoothing 
ma <- autoplot(month, series="Data") +
  autolayer(ma(month,13), series="1 Year MA") +
  xlab("Year") + ylab("GWh") +
  ggtitle("Industrial Sector Fund Stock JAN 2010 - March 2023(1 Year Moving Average)") +
  scale_colour_manual(values=c("Data"="grey50","1 Year MA"="red"),
                      breaks=c("Data","1 Year MA"))
ma

Code
#SMA Smoothing 
ma <- autoplot(month, series="Data") +
  autolayer(ma(month,37), series="3 Year MA") +
  xlab("Year") + ylab("GWh") +
  ggtitle("Industrial Sector Fund Stock JAN 2010 - March 2023(3 Year Moving Average)") +
  scale_colour_manual(values=c("Data"="grey50","3 Year MA"="red"),
                      breaks=c("Data","3 Year MA"))
ma

Code
#SMA Smoothing 
ma <- autoplot(month, series="Data") +
  autolayer(ma(month,61), series="5 Year MA") +
  xlab("Year") + ylab("GWh") +
  ggtitle("Industrial Sector Fund Stock JAN 2010 - March 2023(5 Year Moving Average)") +
  scale_colour_manual(values=c("Data"="grey50","5 Year MA"="red"),
                      breaks=c("Data","5 Year MA"))
ma

The four plots show the Industrial Sector Fund stock prices from JAN 2010 to March 2023, along with the moving averages for 4 months, 1 year 3 years and 4 years. As the window of the moving average increases, the smoother the trend line becomes, reducing the impact of noise and fluctuations in the original time series.

The 4-month moving average plot shows frequent fluctuations in the stock price, with the trend line following the general direction of the time series. The 1-year moving average plot shows a smoother trend, following the overall upward trend of the stock price.

The 1-year moving average plot shows a similar trend to the 4-month plot but is even smoother, with fewer fluctuations. Finally, the 5-year moving average plot shows the smoothest trend, with an almost constant upward slope.As the moving average window increases, the smoother trend allows for a clearer identification of the general trend of the Industrial Sector Fund stock prices over time. From the moving average obtained above we can see that there is upward tend in the stock price of Industrial Sector Fund.

Autocorrelation Time Series

  • ACF
  • PACF
  • ADF Test
Code
#ACF for  data
ggAcf(month)+ggtitle("ACF Plot for Industrial Sector Fund Stock JAN 2010 - March 2023")

Code
#PACF for data
ggPacf(month)+ggtitle("PACF Plot for Industrial Sector Fund Stock JAN 2010 - March 2023")

Code
#check the stationarity
tseries::adf.test(month)

    Augmented Dickey-Fuller Test

data:  month
Dickey-Fuller = -3.334, Lag order = 5, p-value = 0.06807
alternative hypothesis: stationary

In the plot of autocorrelation function, which is the acf graph for monthly data, there are clear autocorrelation in lag. The above lag plots and autocorrelation plot indicates seasonality in the series, which means the series is not stationary. It was also verified using Augmented Dickey-Fuller Test which tells us that as the p value is greater than 0.05, the series is not stationary.

Detrend and Differenced Time Series

  • Linear Fitting Model
  • ACF Plot
Code
fit = lm(myts~time(myts), na.action=NULL) 
summary(fit) 

Call:
lm(formula = myts ~ time(myts), na.action = NULL)

Residuals:
     Min       1Q   Median       3Q      Max 
-31.3040  -2.9466  -0.1944   2.9162  16.8247 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept) -1.203e+04  5.594e+01  -215.0   <2e-16 ***
time(myts)   5.991e+00  2.774e-02   215.9   <2e-16 ***
---
Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Residual standard error: 5.967 on 3277 degrees of freedom
Multiple R-squared:  0.9343,    Adjusted R-squared:  0.9343 
F-statistic: 4.663e+04 on 1 and 3277 DF,  p-value: < 2.2e-16
Code
# plot ACFs
plot1 <- ggAcf(myts, 48, main="Original Data: Industrial Sector Fund Stock Stock Price")
plot2 <- ggAcf(resid(fit), 48, main="Detrended data")
plot3 <- ggAcf(diff(myts), 48, main="First differenced data")
grid.arrange(plot1, plot2, plot3, nrow=3)

The estimated slope coefficient β1, 1.077e+00 With a standard error of 8.693e-02, yielding a significant estimated increase of stock price is very less yearly. Equation of the fit for stationary process: \[\hat{y}_{t} = x_{t}+(2.123e+03)-(1.077e+00)t\]

From the above graph we can say that there is no change in detrended plot and the original data acf plot, it typically means that the data is stationary. But when the first order difference is applied the high correlation is removed but there is no seasonal correlation.

As depicted in the above figure, the series is now stationary and ready for future study.